from QQLoginTool.QQtool import  OAuthQQ
from django.contrib.auth import login
from django.views import View
from django.conf import settings
from django import  http
from . models import  OAuthQQUser
from . utils import generate_access_token,check_access_token
import json
import re
from django_redis import get_redis_connection
from users.models import User

class QQUserView(View):

    def get(self,request):
        """QQ登录的第二个接口"""
        # 1.接收前端发送的查询字符串参数code
        code = request.GET.get('code')
        # 2.校验参数
        if not code:
            return  http.JsonResponse({
                'code':'400',
                'errmsg':'缺少必填的参数'
            })
        # 2.1获取工具类对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            # 3.利用code值向QQ服务器发送请求获取access_token
            access_token = oauth.get_access_token(code)
            # 4.利用access_token向QQ服务器再次发送请求,获取openid
            openid = oauth.get_open_id(access_token)

        except Exception as e:
            return   http.JsonResponse({
                'code':'400',
                'errmsg':'认证失败'
            })
        try:
            # 5.去QQ数据库中取openid
            oauth_qq = OAuthQQUser.objects.get(openid =openid)
        except Exception as e:
            # 6.把openid进行加密,得到一个access_token
            access_token =generate_access_token(openid)
            # 7.返回
            return  http.JsonResponse({
                'code':'300',
                'errmsg':'ok',
                'access_token':access_token
            })
        else:
            user = oauth_qq.user
            #登录成功
            #7.状态保持
            login(request,user)
            response = http.JsonResponse({
                'code':'0',
                'errmsg':'ok'
            })
            # 9.往cookie中写入用户名
            response.set_cookie('username',user.username,max_age=3600*24*14)
            # 10.返回json结果
            return  response
    def post(self,request):
        """qq登录的第三个接口"""
        # 1.接收前端传送的json参数
        dict = json.loads(request.body)
        mobile =dict.get('mobile')
        password =dict.get('password')
        sms_code_clint =dict.get('sms_code')
        access_token =dict.get('access_token')
        # 2.总体校验前端传的参数
        if not all([mobile,password,sms_code_clint,access_token]):
            return http.JsonResponse({
                'code':400,
                'errmsg':'缺少必填参数'
            })
        # 3.mobile手机号检验
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return http.JsonResponse({
                'code':400,
                'errmsg':'mobile格式错误'
            })
        # 4.password密码检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.JsonResponse({
                'code': 400,
                'errmsg': 'password格式错误'
            })
        # 5.链接redis,获取redis对象
        redis_coon=get_redis_connection('verify_code')
        # 6.取出服务端的验证码是否存在
        sms_code_server=redis_coon.get('sms_%s'% mobile)
        if not sms_code_server:
            return http.JsonResponse({
                'code': 400,
                'errmsg': '验证码过期'
            })
        # 7.对比前后端验证码
        if sms_code_clint != sms_code_server.decode():
            return http.JsonResponse({
                'code': '400',
                'errmsg': '对比失败'
            })
        # 8.把access_token解密
        openid = check_access_token(access_token)
        if not openid:
            return http.JsonResponse({
                            'code': '400',
                            'errmsg': 'openid解密失败'
                        })
        # 9.根据User表中的mobile尝试取出数据
        try:
            user=User.objects.get(mobile=mobile)
        except Exception as e:
            # 11.如果没有,把mobile信息保存到user中
            user=User.objects.create_user(username=mobile,password=password,mobile=mobile)
        else:
            # 10.如果有,校验密码
            if not user.check_password(password):
                return http.JsonResponse({
                    'code': '400',
                    'errmsg': '密码有误'
                })
        # 12.检查QQ表中是否有openid,如果没有就进行存储
        try:
            oauth_qq =OAuthQQUser.objects.get(openid=openid)
        except Exception as e:
            oauth_qq=OAuthQQUser.objects.create(openid=openid,user=user)
        # 13.状态保持
        login(request,user)
        response = http.JsonResponse({
            'code':0,
            'errmsg':'ok'
        })
        # 14.往cookie中写入username
        response.set_cookie('username',user.username,max_age=3600*24*14)
        # 15.返回响应
        return response



class QQFirstView(View):


    def get(self,request):
        """QQ登录的第一个接口,返回QQ登录页面的网址"""
        # 1.接收可能前端传来的参数next,以查询字符串的方式传入
        next=request.GET.get('next')
        # 2.获取工具类对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)
        # 3.调用工具类的方法,获取qq的url
        url=oauth.get_qq_url()
        # 4.返回json
        return http.JsonResponse({
            'code':'0',
            'errmsg':'ok',
            'login_url':url
        })